package org.game.config;

import java.io.FileNotFoundException;
import java.util.Date;

import javax.script.ScriptException;

import org.ConfigLoad;
import org.apache.activemq.jms.pool.PooledConnectionFactory;
import org.game.cache.ServerCache;
import org.game.constant.GameConstant;
import org.game.constant.QuartzCronExpressions;
import org.game.constant.RemoteModuleEnum;
import org.game.db.PlayerIdProvider;
import org.game.db.SnowflakeIdProviderFactory;
import org.game.manager.EndlessCloisterManager;
import org.game.manager.GameServerManager;
import org.game.module.datingbo.trigger.CityDatingTriggerManager;
import org.game.module.playerbo.PlayerFactory;
import org.game.netty.oldcoder.other.HuanjieMessageFactory;
import org.game.netty.session.NettySessionFactory;
import org.game.plugin.DBSavePlugin;
import org.game.plugin.NettyServerPlugin;
import org.game.plugin.VerifyCsvPlugin;
import org.game.plugin.event.GameEventPlugin;
import org.game.quartz.InviteDatingJob;
import org.game.quartz.MinuteJob;
import org.game.quartz.SecondsJob;
import org.game.quartz.UpdateRoleMoodJob;
import org.script.ScriptManager;
import org.springframework.jms.connection.SingleConnectionFactory;
import org.springframework.jms.listener.DefaultMessageListenerContainer;
import org.utils.RemoteUtil;

import com.sojoys.artifact.config.Constants;
import com.sojoys.artifact.config.Modules;
import com.sojoys.artifact.config.Plugins;
import com.sojoys.artifact.constant.ServerStatusEnum;
import com.sojoys.artifact.core.IConfig;
import com.sojoys.artifact.core.IServer;
import com.sojoys.artifact.factory.bytebuff.NettyByteBuffFactory;
import com.sojoys.artifact.factory.json.FastJsonFactory;
import com.sojoys.artifact.factory.remote.ActiveMQRemoteProxyFactory;
import com.sojoys.artifact.manager.ContextManager;
import com.sojoys.artifact.manager.DistributedIdManager;
import com.sojoys.artifact.manager.PropManager;
import com.sojoys.artifact.manager.ThreadManager;
import com.sojoys.artifact.plugin.actor.ActorPlugin;
import com.sojoys.artifact.plugin.dirtyword.DirtyWordsPlugin;
import com.sojoys.artifact.plugin.i18n.I18NPlugin;
import com.sojoys.artifact.plugin.netty.web.NettyWebPlugin;
import com.sojoys.artifact.plugin.quartz.QuartzPlugin;
import com.sojoys.artifact.plugin.syncdatabase.SyncMysqlPlugin;
import com.xiaoleilu.hutool.log.Log;
import com.xiaoleilu.hutool.log.LogFactory;

/**
 * @author : DengYing
 * @CreateDate : 2017年7月31日 下午3:56:15
 * @Description ：Please describe this document
 */
public class GameConfig implements IConfig {
	static Log log = LogFactory.get(GameConfig.class);

	@Override
	public void configConstant(Constants me) {
	    try{
    		// 设置使用的配置文件
    		PropManager.use("app.properties");
    		
    		// SpringContext初始化
    		ContextManager.me().init("app-init.xml");
    		
    		me.setRemoteProxyFactory(new ActiveMQRemoteProxyFactory());
    		
    		me.setByteBuffFactory(new NettyByteBuffFactory());
    		
    		me.setJsonFactory(new FastJsonFactory());
    		
    		me.setSessionFactory(new NettySessionFactory());
    		
    		me.setMessageFactory(new HuanjieMessageFactory());
    
    		me.setDistributedIdProviderFactory(new SnowflakeIdProviderFactory());
    		
    		// 脚本初始化
    		initScriptManager();
    		
    	} catch (Exception e) {
            e.printStackTrace();
            System.exit(0);
        }
	}

	@Override
	public void configModules(Modules me) {
		// 逻辑Module注册
		me.add(new ModuleScan());
	}

	@Override
	public void configPlugin(Plugins me) {
		// 注意：插件先后顺序影响 插件的启动和停止顺序(即为:先启动 先停止)
		me.add(new SyncMysqlPlugin());
		
		// 国际化插件
		me.add(new I18NPlugin());

		// 屏蔽字插件
		me.add(new DirtyWordsPlugin());

		// Netty服务插件
		me.add(new NettyServerPlugin());

		// Netty-WEB服务插件
		me.add(new NettyWebPlugin(null));

		// 事件处理插件
		me.add(new GameEventPlugin());

		// 定时插件
		me.add(new QuartzPlugin());
		
		// 停止Actor插件
		me.add(new ActorPlugin());

		// 数据定时存储插件
		me.add(new DBSavePlugin());
		
		// CSV同步插件
		me.add(new VerifyCsvPlugin());
	}

	@Override
	public void afterServerStart() {
		try {
			// 所有配置加载
			ConfigLoad.loadAllCsv(GameConfig.class.getClassLoader().getResource("gameConfig").getPath() + "/");
						
			startActiveMQ();
			
			// 通知游戏服务器
			RemoteUtil.loginAsyn().gameServerStart();
			
			// 通知社交服务器
			RemoteUtil.socialAsyn().gameServerStart(PropManager.get(GameConstant.GAME_SERVER_ID));
			
			// 请求分布式ID集
			DistributedIdManager.me().getProvider().syncLoad();
			
			// 玩家ID数据提供器
			PlayerIdProvider.me().syncLoad();
			
	        // 无尽回廊初始化
            EndlessCloisterManager.me().init();

			// 预创建玩家
			PlayerFactory.me().init();
			
			// 请求全服限购商品购买记录
//			ServerLimitCommodityBuyRecordCache.me().syncLoad();

//			// 请求动态商品信息
//			CommodityCfgCache.me().syncLoadDynamic();
			
			// 每秒定时器
			QuartzPlugin.addJob("SecondsJob", "SecondsJob", new Date(), "0/1 * * * * ?", SecondsJob.class, null);
			
			// 分钟定时器
			QuartzPlugin.addJob("MinuteJob", "MinuteJob", new Date(), "0 * * * * ? *", MinuteJob.class, null);
			
			// 看板娘心情值quartz
			QuartzPlugin.addJob("UpdateRoleMoodJob", "UpdateRoleMoodJob", new Date(), QuartzCronExpressions.ROLE_MOOD_UPDATE_TIME, UpdateRoleMoodJob.class, null);

			//预定约会触发定时器
			QuartzPlugin.addJob("InviteDatingJob", "InviteDatingJob", new Date(), QuartzCronExpressions.INVITE_DATING_TIME, InviteDatingJob.class, null);

//			ReserveDatingRule.loadRule();

			// 缓存所有玩家简单信息
			ServerCache.loadAll();
			
			// 等待远程模块初始化
			boolean await = true;
			while (await) {
				RemoteModuleEnum[] remoteModule = RemoteModuleEnum.values();
				boolean initAll = true;
				for (RemoteModuleEnum remoteModuleEnum : remoteModule) {
					initAll &= remoteModuleEnum.isInit();
				}
				await = !initAll;
				if (await) {
					// 等等
					Thread.sleep(100);
				}
			}
			// 同步社交服维护状态
			int status = RemoteUtil.socialSync().getStatus();
			ServerStatusEnum en = ServerStatusEnum.AEGIS;
			for (ServerStatusEnum e : ServerStatusEnum.values()) {
                if(e.getCode()==status){
                    en = e;
                    break;
                }
            }
			IServer.SERVER_STATUS = en;
			log.info("----server status = "+IServer.SERVER_STATUS);
			log.info("************ Server Start Finish ************");
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(0);
		}
	}

	@Override
	public void beforeServerStop() {
		// ThreadPoolTaskExecutor task =
		// ThreadManager.me().getThreadPoolTaskExecutor("taskExecutor");
		// task.shutdown();
		ThreadManager.me().stop();

		stopAcriveMQ();
	}
	
    /**
     * 初始化脚本系统
     * 
     * @throws ScriptException
     * @throws FileNotFoundException
     */
    private void initScriptManager() throws FileNotFoundException, ScriptException {
        ScriptManager.getInstance().initialize("scripts/java", "./scriptBin");
    }

	private void startActiveMQ(){
		DefaultMessageListenerContainer topicListenerContainer = ContextManager.me().getBean("topicListenerContainer", DefaultMessageListenerContainer.class);
		topicListenerContainer.start();
		
		DefaultMessageListenerContainer queueListenerContainer = ContextManager.me().getBean("queueListenerContainer", DefaultMessageListenerContainer.class);
		queueListenerContainer.start();
	}
	
	private void stopAcriveMQ() {
		DefaultMessageListenerContainer topicListenerContainer = ContextManager.me().getBean("topicListenerContainer",
				DefaultMessageListenerContainer.class);
		topicListenerContainer.destroy();

		DefaultMessageListenerContainer queueListenerContainer = ContextManager.me().getBean("queueListenerContainer",
				DefaultMessageListenerContainer.class);
		queueListenerContainer.destroy();

		PooledConnectionFactory pooledConnectionFactory = ContextManager.me().getBean("pooledConnectionFactory",
				PooledConnectionFactory.class);
		pooledConnectionFactory.stop();

//		SingleConnectionFactory singleConnectionFactory = ContextManager.me().getBean("singleConnectionFactory",
//				SingleConnectionFactory.class);
//		singleConnectionFactory.destroy();
	}

	public static void main(String[] args) throws Exception {
		String path = "D:/workspace/All/game/src/main/resources/dev/gameConfig/";
		// 所有配置加载
		ConfigLoad.loadAllCsv(path);

		// RoleCfgCache.me().loadCsv(SK_Plus.b(path, "Role.csv").e());
		// List<RoleCfg> lists = RoleCfgCache.me().getAll();
		// for (RoleCfg growUpCfg : lists) {
		// System.out.println(growUpCfg.toMap(DataModelKeyEnum.SOURCE));
		// }

		// ItemCfgCache.me().loadCsv(SK_Plus.b(gameConfig, "Item.csv").e());
		// List<ItemCfg> lists = ItemCfgCache.me().getAll();
		// for (ItemCfg growUpCfg : lists) {
		// System.out.println(growUpCfg.toMap(DataModelKeyEnum.SOURCE));
		// }

		// MainLineCfgCache.me().loadCsv(SK_Plus.b(path, "MainLine.csv").e());
		// List<MainLineCfg> lists1 =
		// MainLineCfgCache.me().getByChapterGroupId(1001);
		// for (MainLineCfg mainLineCfg : lists1) {
		// System.out.println(mainLineCfg.toMap(DataModelKeyEnum.SOURCE));
		// }
	}

	@Override
	public void startSucceed() {
		GameServerManager.me().registerGameServerInfo();
	}
}
